using SqlSugar;

namespace DiLu.Expansion.DataStorage.SqlSugarExpansion;

/// <summary>
///     表示一个基于SqlSugar的仓储类，用于执行数据库操作。此类继承自SimpleClient，并且支持多租户环境下的数据隔离。
/// </summary>
/// <typeparam name="T">泛型参数，表示该仓储操作的数据实体类型。</typeparam>
public class SqlSugarRepository<T> : SimpleClient<T> where T : class, new()
{
    /// <summary>
    ///     代表当前数据操作的租户信息，用于多租户环境下的数据隔离。
    /// </summary>
    public readonly ITenant Tenant;

    /// <summary>
    ///     表示一个基于SqlSugar的仓储类，用于执行数据库操作。此类继承自SimpleClient，并且支持多租户环境下的数据隔离。
    /// </summary>
    /// <typeparam name="T">泛型参数，表示该仓储操作的数据实体类型。</typeparam>
    /// <param name="db">ISqlSugarClient类型的参数，提供对数据库的基本访问功能。</param>
    public SqlSugarRepository(ISqlSugarClient db)
    {
        Tenant = db.AsTenant();
        base.Context = db.AsTenant().GetConnectionWithAttr<T>();
    }

    /// <summary>
    ///     获取一个动态的数据库连接范围，支持多租户环境下的数据隔离，并允许自定义配置和行为。
    /// </summary>
    /// <typeparam name="TOperateAccountId">泛型参数，用于指定操作账户ID的数据类型。</typeparam>
    /// <param name="connectionConfig">连接配置对象，包含数据库连接所需的信息。</param>
    /// <param name="recordLogSecond">记录日志的时间间隔（秒），用于控制执行后日志的记录频率。</param>
    /// <param name="dataExecutingAction">可选参数，SQL执行前的数据过滤操作，通过传入此委托可以对即将执行的SQL进行数据层面的修改或检查。</param>
    /// <param name="moreSettingAction">可选参数，提供更多连接设置选项的委托，允许用户进一步调整当前数据库连接的行为。</param>
    /// <param name="moreSugarScopeProvider">可选参数，针对SqlSugarScopeProvider对象的额外配置委托，可用于扩展或修改SqlSugar客户端的功能。</param>
    /// <returns>返回一个SqlSugarScopeProvider实例，该实例封装了指定配置下的数据库连接，并应用了所有提供的自定义设置和行为。</returns>
    public SqlSugarScopeProvider GetDynamicConnectionScope<TOperateAccountId>(ConnectionConfig connectionConfig, int recordLogSecond,
        Action<object, DataFilterModel> dataExecutingAction = null, Action<ConnMoreSettings> moreSettingAction = null,
        Action<SqlSugarScopeProvider> moreSugarScopeProvider = null)
    {
        if (Tenant.IsAnyConnection(connectionConfig.ConfigId))
            return Tenant.GetConnectionScope(connectionConfig.ConfigId);

        Tenant.AddConnection(connectionConfig);
        var dynamicConnection = Tenant.GetConnectionScope(connectionConfig.ConfigId);

#if DEBUG
        //添加SQL执行前的事件，用于在SQL执行前记录日志
        dynamicConnection.AddLogExecuting($"{connectionConfig.ConfigId}");
#endif
        //添加SQL执行后的事件，用于在SQL执行后记录日志
        dynamicConnection.AddLogExecuted(recordLogSecond);

        //添加SQL执行后错误事件，用于在SQL执行出现错误时记录日志
        dynamicConnection.AddSqlErrorLog();

        //添加数据过滤器，在SQL执行前对数据进行过滤
        dynamicConnection.AddDataExecuting<TOperateAccountId>(dataExecutingAction);

        //更多连接设置
        var moreSettings = new ConnMoreSettings
            { IsWithNoLockQuery = true, SqlServerCodeFirstNvarchar = true, IsNoReadXmlDescription = true };
        moreSettingAction?.Invoke(moreSettings);
        dynamicConnection.CurrentConnectionConfig.MoreSettings = moreSettings;

        //更多SqlSugar对象中间件服务
        moreSugarScopeProvider?.Invoke(dynamicConnection);

        return dynamicConnection;
    }
}